// 输入: pattern = "abba", str = "abba"
// 输出: true

function p1 (pattern, str) {
    const arr = str.split(' ');
    if (pattern.length !== arr.length) {
        return false;
    }
    const record = {};
    // { dog: 'a', $a: 'dog', cat: 'b', $b: 'cat' }
    for (let i = 0; i < arr.length; i++) {
        const word = arr[i]; // dog
        // false !== false
        // false !== false
        // true !== true
        const p = pattern[i];
        if (!!record[word] !== !!record['$' + p]) {
            return false;
        } else {
            if (!record[word]) {
                record[word] = p; // { dog: 'a' }
                record['$' + p] = word; // { a: 'dog' }
            } else {
                if (record[word] !== p) {
                    return false;
                }
            }
        }
    }
    return true;
}

function p2 (pattern, s) {
    const p = pattern.split('')
    const str = s.split(' ')
    if(p.length !== str.length) {
        return false
    }
    // O(N ** 2)
    for(let i = 0; i < p.length; i++) {  // O(N)
        if(p.indexOf(p[i]) !== str.indexOf(str[i])) { // O(N) * 2
            return false
        }
    }
    return true
}

var p3 = function(pattern, s) {
    let arrPattern = pattern.split('')
    let arrS = s.split(' ')
    const mapping = {}
    if (arrPattern.length !== arrS.length) {
        return false
    }
    // O(N ** 3)
    for (let i = 0; i < arrPattern.length; i++) {
        let currentPattern = arrPattern[i]
        let currentS = arrS[i]
        if (mapping[currentPattern] !== undefined) {
            if (mapping[currentPattern] !== currentS) {
                return false
            }
        } else {
            mapping[currentPattern] = currentS
            let mappingValue = Object.values(mapping)
            //查找是否有相同的值,不同的键
            if (mappingValue.length !== [...new Set(mappingValue)].length) {
                return false
            }
        }
    }
    return true
};

        function p4(pattern, str) {
            const word2ch = new Map();
            const ch2word = new Map();
            const words = str.split(' ');
            if (pattern.length !== words.length) {
                return false;
            }
            // O(N)
            for (const [i, word] of words.entries()) {
                const ch = pattern[i];
                if (word2ch.has(word) && word2ch.get(word) != ch || ch2word.has(ch) && ch2word.get(ch) !== word) {
                    return false;
                }
                word2ch.set(word, ch);
                ch2word.set(ch, word);
            }
            return true;
        };

      function p5 (pattern, s){
           const lenPattern = pattern.length
           const arr = s.split(' ')
           const obj = {}
           const obj2 = {}
           if( lenPattern !== arr.length){
               return false
           }
           // O(N)
           for(let i = 0; i < lenPattern; i++){
               if(obj[pattern[i]] === undefined){
                obj[pattern[i]] = arr[i]
               }else if(obj[pattern[i]] !== arr[i]){
                    return false
               }
               obj2[arr[i]] = arr[i]
           }
           const valuesLeg1 = Object.values(obj).length
           const valuesLeg2 = Object.values(obj2).length
           if(valuesLeg1 !== valuesLeg2){
               return false
           }
           return true
       }
// console.log(isMatchPattern('abba', 'dog cat cat cat'));
// console.log(getJudge('abba', 'dog cat cat fish'));


function performance (name, cb, count = 100) {
    console.time(name);
    for (let i = 0; i < count; i++) {
        cb();
    }
    console.timeEnd(name);
}

const words = ['dog', 'cat', 'fish', 'cat1', 'fish1', 'cat2', 'fish2', 'cat3', 'fish3', 'cat4', 'fish4'];
const tpl = 'qwertyuiolk';
const data = new Array(5000).fill(0).map(() => words[Math.floor(Math.random() * 11)]).join(' ');
const pattern = new Array(5000).fill(0).map(() => tpl[Math.floor(Math.random() * 11)]).join('');
// console.log(pattern, data)

performance('1', () => {
    p1(pattern, data);
});

performance('2', () => {
    p2(pattern, data);
});

performance('3', () => {
    p3(pattern, data);
});

performance('4', () => {
    p4(pattern, data);
});

performance('5', () => {
    p5(pattern, data);
});

